<template>
  <el-drawer v-model="modelValue" :title="$t('staff_list.quick_edit')">
    <el-form v-loading="loading" ref="formRef" label-position="top" :model="formValue" :rules="formRules">
      <el-form-item prop="employee_name" :label="$t('staff_list.employee_name')">
        <el-input v-model="formValue.employee_name" v-trim class="qf_input" />
      </el-form-item>
      <el-form-item prop="employee_alias" :label="$t('staff_list.employee_alias')">
        <el-input v-model="formValue.employee_alias" v-trim class="qf_input" />
      </el-form-item>
      <el-form-item :label="$t('staff_list.mobile')">
        <el-row style="width: 100%">
          <el-col :span="6">
            <el-form-item prop="country_code">
              <el-select v-model="formValue.country_code" class="qf_select" filterable>
                <el-option v-for="option in options.countryOptions" :value="option.value" :label="option.label" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="2">
            <div style="text-align: center">-</div>
          </el-col>
          <el-col :span="16">
            <el-form-item prop="mobile">
              <el-input
                v-model="formValue.mobile"
                v-number
                class="qf_input"
                @input="value => (formValue.mobile = value.replace('+', ''))"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form-item>
      <el-form-item prop="username" :label="$t('staff_list.username')">
        <el-input v-model="formValue.username" v-trim class="qf_input" />
      </el-form-item>
      <el-form-item prop="password" :label="$t('staff_list.password')">
        <el-input v-model="formValue.password" v-trim class="qf_input" placeholder="******" />
      </el-form-item>
      <el-form-item prop="org_group" :label="$t('staff_list.org_group')">
        <TreeSelect class="qf_select" v-model:value="org_group" :options="options.orgOptions" />
      </el-form-item>
      <el-form-item prop="direct_superiors" :label="$t('staff_list.direct_superiors')">
        <el-select v-model="formValue.direct_superiors" class="qf_select" filterable>
          <el-option v-for="option in options.superiorOptions" :value="option.value" :label="option.label" />
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <div style="text-align: right">
        <el-button @click="() => (modelValue = false)">取消</el-button>
        <el-button type="primary" :loading="saveLoading" @click="handleSave">保存</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import { getCurrentInstance, ref, reactive, computed, watch, onMounted } from "vue";

import { FormRules, ElMessage, ElDrawer, ElForm, ElFormItem, ElRow, ElCol, ElInput, ElSelect, ElOption } from "element-plus";

import TreeSelect from "@/components/MerakXFormItem/components/TreeSelect.vue";

import { ResultEnum } from "@/enums/httpEnum";
import {
  TreeOptionType,
  getDictOptions,
  getOrgTreeOptions,
  checkDuplicate,
  getPersonnelInfo,
  savePersonnelInfo
} from "@/api/modules/sysManage/personnel";

import { confirmWarningMsg } from "@/utils/messageUtils";

type OptionType = {
  value: string | number;
  label: string;
  children?: OptionType[];
};

const props = defineProps<{ userId?: string | number }>();

const emit = defineEmits<{
  close: [];
}>();

const modelValue = defineModel({ default: false });

const currentInstance = getCurrentInstance();

const formRef = ref<InstanceType<typeof ElForm>>();

const loading = ref(false);

const saveLoading = ref(false);

const options = reactive<{ countryOptions: OptionType[]; superiorOptions: OptionType[]; orgOptions: OptionType[] }>({
  countryOptions: [],
  superiorOptions: [],
  orgOptions: []
});

const formValue = reactive<Record<string, any>>({});

const formRules = reactive<FormRules>({
  employee_name: [
    {
      required: true,
      trigger: "change",
      validator: (rule, value, callback) => {
        let reg = /[\d~`!@#$%^&*()\-_=+[\]{}|;:'",<.>/?]+/g;
        if (!value) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.employee_name_valid")));
        } else if (reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.employee_name_valid_limit")));
        } else {
          callback();
        }
      }
    }
  ],
  employee_alias: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        const reg = /[~`!@#$%^&*()\-_=+[\]{}|;:'",<.>/?]+/g;
        if (reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.employee_alias_valid_limit")));
        } else {
          callback();
        }
      }
    }
  ],
  country_code: [{ required: true, message: currentInstance?.proxy?.$t("staff_list.country_code_valid") }],
  mobile: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        let reg: RegExp;
        console.log(value);
        switch (formValue.country_code) {
          case 86:
            reg = /^1\d{10}$/;
            break;
          // case 7:
          //   reg = /^\d{10}$/;
          //   break;
          // case 375:
          //   reg = /^\d{9}$/;
          //   break;
          // case 374:
          //   reg = /^\d{8}$/;
          //   break;
          default:
            reg = /^[1-9]\d*$/;
            break;
        }
        if (!value) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.mobile_valid")));
        } else if (reg.test(value)) {
          callback();
        } else {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.mobile_valid_limit")));
        }
      }
    }
  ],
  username: [
    {
      required: true,
      validator: (rule, value, callback) => {
        const reg = /^[\w\s]*$/;
        if (!value) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.username_valid")));
        } else if (reg.test(value)) {
          callback();
        } else {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.username_valid_limit")));
        }
      }
    },
    {
      trigger: "blur",
      validator: (rule, value, callback) => {
        checkDuplicate({ field: "username", value, user_id: props.userId?.toString() }).then(({ code, message }) => {
          if (code == ResultEnum.SUCCESS) {
            callback();
          } else {
            callback(new Error(message as string));
          }
        });
      }
    }
  ],
  password: [
    {
      trigger: "change",
      validator: (rule, value, callback) => {
        const reg = /^[a-zA-Z]\w{5,17}$/;
        if (!!value && !reg.test(value)) {
          callback(new Error(currentInstance?.proxy?.$t("staff_list.password_valid_limit")));
        } else {
          callback();
        }
      }
    }
  ]
});

const org_group = computed({
  get() {
    const values: string[] = [];
    const queryValue = (value: string, level: number, options: OptionType[]) => {
      for (let option of options) {
        const optionValues = (option.value as string).split("-");
        if (optionValues.length === level && optionValues[optionValues.length - 1] === value) {
          return option.value;
        } else if (!!option.children?.length && !!queryValue(value, level, option.children)) {
          return queryValue(value, level, option.children);
        }
      }
    };
    const companyValues = [...(formValue.org_company ?? [])]
      .map(value => queryValue(value.toString(), 1, options.orgOptions))
      .filter(Boolean) as string[];
    const departmentValues = [...(formValue.org_department ?? [])]
      .map(value => queryValue(value.toString(), 2, options.orgOptions))
      .filter(Boolean) as string[];
    const titleValues = [...(formValue.org_title ?? [])]
      .map(value => queryValue(value.toString(), 3, options.orgOptions))
      .filter(Boolean) as string[];
    // 遍历公司id的集合
    for (let companyValue of companyValues) {
      // 判断部门id的集合中是否有存在该公司下的部门
      if (departmentValues.some(departmentValue => departmentValue.includes(`${companyValue}-`))) {
        // 遍历部门id的集合
        for (let departmentValue of departmentValues) {
          // 判断部门存在该公司下
          if (departmentValue.includes(`${companyValue}-`)) {
            // 判断岗位id的集合中是否有存在该部门下的岗位
            if (titleValues.some(titleValue => titleValue.includes(`${departmentValue}-`))) {
              // 遍历岗位id的集合
              for (let titleValue of titleValues) {
                // 判断岗位存在该部门下
                if (titleValue.includes(`${departmentValue}-`)) {
                  values.push(titleValue);
                }
              }
            } else {
              // 当部门存在该公司下并且岗位集合中不存在该部门的岗位
              values.push(departmentValue);
            }
          }
        }
      } else {
        // 当部门集合中不存在该公司的部门
        values.push(companyValue);
      }
    }
    return [...new Set(values)];
  },
  set(values) {
    const org_company: number[] = [];
    const org_department: number[] = [];
    const org_title: number[] = [];
    for (let value of values) {
      const [company, department, title] = value.split("-");
      if (!!company) {
        org_company.push(Number(company));
      }
      if (!!department) {
        org_department.push(Number(department));
      }
      if (!!title) {
        org_title.push(Number(title));
      }
    }
    formValue.org_company = org_company;
    formValue.org_department = org_department;
    formValue.org_title = org_title;
  }
});

const handleSave = () => {
  formRef.value
    ?.validate()
    .then(() => {
      saveLoading.value = true;
      savePersonnelInfo({ user_id: props.userId, ...formValue }).then(({ code, message }) => {
        if (code == ResultEnum.SUCCESS) {
          emit("close");
          ElMessage.success(currentInstance?.proxy?.$t("staff_list.save_employee_info_success"));
        } else {
          const msg = typeof message === "string" ? message : Object.values(message)?.[0];
          ElMessage.error(msg);
        }
        saveLoading.value = false;
      });
    })
    .catch(err => {
      const first = Object.keys(err)?.[0];
      if (!!first) {
        formRef.value?.scrollToField(first);
      }
    });
};

watch(
  () => props.userId,
  async () => {
    if (!props.userId) return;
    loading.value = true;
    await getPersonnelInfo(props.userId.toString()).then(({ code, data }) => {
      if (code == ResultEnum.SUCCESS) {
        Object.assign(formValue, {
          employee_name: data.employee_name,
          employee_alias: data.employee_alias,
          country_code: data.country_code,
          mobile: data.mobile,
          username: data.username,
          password: data.password,
          org_company: data.org_company,
          org_department: data.org_department,
          org_title: data.org_title,
          direct_superiors: data.direct_superiors
        });
      }
    });
    loading.value = false;
  }
);

onMounted(() => {
  getDictOptions({ key: "country_code" }).then(({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      options.countryOptions = [...(data ?? [])].map(option => ({ value: option.key, label: option.value }));
    }
  });
  getDictOptions({ key: "direct_superiors" }).then(({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      options.superiorOptions = [...(data ?? [])].map(option => ({ value: option.key, label: option.value }));
    }
  });
  getOrgTreeOptions().then(({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      const generate = (list: TreeOptionType[], parentId?: string) => {
        const arr: OptionType[] = [];
        for (let item of list) {
          const payload: OptionType = {
            value: `${!!parentId ? parentId + "-" : ""}${item.key}`,
            label: item.value
          };
          if (!!item.sublevel?.length) {
            payload.children = generate(item.sublevel, payload.value as string);
          }
          arr.push(payload);
        }
        return arr;
      };
      options.orgOptions = generate([...(data ?? [])]);
    }
  });
});
</script>

<style scoped lang="scss"></style>
